/************************************************************************
<4loco-aprs.  This program connects to a specified APRS server and displays
    the information on a map. It's being developed using QT Creator. The project
    began in February and version 1 should be released in April. For more
    information go to http://code.google.com/p/4loco-aprs/>

    Copyright (C) <2011>  <Kyle Roden, Glen Riden, Aaron Smith, Alisa Emerich>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/

#include "connectionmanager.h"
#include "ui_connectionmanager.h"
#include "errordialog.h"
ConnectionManager::ConnectionManager(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ConnectionManager)
{
    ui->setupUi(this);
    ui->pushButton->hide();
    ui->pushButton_2->hide();
    ui->checkBox->hide();

    setWindowTitle("Connection Manager");

    // Open the connections database
    connectionsDatabase = QSqlDatabase::addDatabase("QSQLITE", "connections");
    connectionsDatabase.setDatabaseName("../config.db");
    if (!connectionsDatabase.open()) // Make sure the database opens successfully
    {
        qDebug() << "Database Error :: NEAR LINE 16";
        qDebug() << connectionsDatabase.lastError();
    }

    if (!connectionsDatabase.tables().contains("connections"))
        CreateNewTable(); // Create a new table for connections if it does not exist.

    ui->LE_Password->setEchoMode(QLineEdit::Password);

    // For now, disable TNC radio button and check Internet
    ui->PB_DeleteConnection->setEnabled(false);

    PopulateConnectionsListWidget(); // Fill in the empty list widget box


    // Signals and Slots
    connect(ui->PB_Save, SIGNAL(clicked()), this, SLOT(SaveIsClicked()));
    connect(ui->PB_Clear, SIGNAL(clicked()), this, SLOT(ClearAllBoxes()));
   // connect(ui->listWidget, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(ItemSelected()));
    connect(ui->listWidget,SIGNAL(itemClicked(QListWidgetItem*)),this, SLOT(ItemSelected()));
    connect(ui->PB_DeleteConnection, SIGNAL(clicked()), this, SLOT(DeleteConnection()));
    connect(ui->LE_ConnectionName, SIGNAL(textChanged(QString)), this, SLOT(CheckIfConnectionExists()));
    connect(ui->PB_Close, SIGNAL(clicked()), this, SLOT(close()));
    connect(ui->PB_NewConnection, SIGNAL(clicked()), this, SLOT(CreateNewConnection()));
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(buttonPushed()));
    connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(disconnectButtonPushed()));
}

ConnectionManager::~ConnectionManager()
{
    delete ui;
}

void ConnectionManager::CheckIfConnectionExists()
{
    QSqlQuery checkQuery(connectionsDatabase);
    checkQuery.exec("SELECT * FROM connections;");

    while (checkQuery.next())
    {
        if (checkQuery.value(0).toString() == ui->LE_ConnectionName->text())
        {
            if (connectionBeingCreated)
            {
                ui->PB_Save->setDisabled(true);
                ui->LA_ErrorStatus->setText("<font color=\"red\">ERROR: </font>Connection name already exists.");
                ui->PB_DeleteConnection->setDisabled(true);
            }
            else
                ui->PB_DeleteConnection->setEnabled(true);
            break;
        }
        else
        {
            ui->PB_Save->setEnabled(true);
            ui->LA_ErrorStatus->setText("");
            ui->PB_DeleteConnection->setEnabled(false);
        }
    }
}

void ConnectionManager::ClearBoxes()
{
    // Clear all boxes
    ui->LE_ConnectionName->setText("");
    ui->LE_FilterString->setText("");
    ui->LE_Password->setText("");
    ui->LE_Port->setText("");
    ui->LE_ServerIP->setText("");
    ui->LE_Username->setText("");
}

void ConnectionManager::PopulateConnectionsListWidget()
{
    // This function populates the list widget from the database with connections.
    ui->listWidget->clear(); // clear it first

    QSqlQuery populateQuery(connectionsDatabase);
    QString populateString;
    populateQuery.exec("SELECT * FROM connections");

    while (populateQuery.next())
    {
        // Populates the list widget with connections
        // Format:  (CONNECTION NAME)
        // Connection Name = Value 0
        populateString = populateQuery.value(0).toString();
        ui->listWidget->addItem(populateString);
    }
}

void ConnectionManager::CreateNewTable()
{
    /**********************************
      Connection Database
      ================
      Connection Name
      Server IP
      Server Port
      Username
      Password
      Filter
    ***********************************/
    QSqlQuery newTableQuery(connectionsDatabase);
    newTableQuery.exec("CREATE TABLE connections ("
                   "connection_name STRING, "
                   "server_ip STRING, "
                   "server_port INT, "
                   "username STRING, "
                   "password STRING, "
                   "filter STRING"
                   ");");
}

void ConnectionManager::buttonPushed(){

    if(ui->LE_ServerIP->text().isEmpty()){
        ErrorDialog errorDialog(this);
        errorDialog.setModal(true);
        errorDialog.setErrorText(" You need to select a server first!");
        errorDialog.exec();
        return;
    }
    emit connectPushed(ui->LE_ConnectionName->text());
}

void ConnectionManager::disconnectButtonPushed(){

    if(ui->LE_ServerIP->text().isEmpty()){
        ErrorDialog errorDialog(this);
        errorDialog.setModal(true);
       // errorDialog.ad
        errorDialog.setErrorText(" You need to select a server first!");
        errorDialog.exec();
        return;
    }

    emit disconnectPushed(ui->LE_ConnectionName->text());
}

void ConnectionManager::SaveIsClicked()
{
    // This slot needs to
    // (1) Write the information in the database
    // (2) Reload the database in to the list widget (using the "PopulateConnectionsListWidget" function)

    /*** (1) ***/
    // Variable declarations and initializations
    bool alreadyExists = false;

    QString connection_name = ui->LE_ConnectionName->text();
    QString username = ui->LE_Username->text();
    QString password = ui->LE_Password->text();
    QString server_ip = ui->LE_ServerIP->text();
    QString server_port = ui->LE_Port->text();
    QString filter_string = ui->LE_FilterString->text();

    if (connection_name == "") // Do not accept a blank connection name
    {
        ui->LA_ErrorStatus->setText("<font color=\"red\">ERROR</font>: A connection name is REQUIRED!");
        return;
    }
    else
    {
       ui->LA_ErrorStatus->setText("");
       ui->LE_FilterString->setDisabled(true);
       ui->LE_Password->setDisabled(true);
       ui->LE_Port->setDisabled(true);
       ui->LE_ServerIP->setDisabled(true);
       ui->LE_Username->setDisabled(true);
    }

    QSqlQuery entryCheckQuery(connectionsDatabase);
    QSqlQuery updatingQuery(connectionsDatabase);

    // Check if the connection's name is already in use - if it is, overwrite the old settings.
    entryCheckQuery.exec("SELECT * FROM connections");
    while (entryCheckQuery.next())
    {
        if (connection_name == entryCheckQuery.value(0).toString())
        {
            alreadyExists = true;
            break;
        }
        else
        {
            alreadyExists = false;
        }
    }

    if (alreadyExists)
    {
        updatingQuery.prepare("UPDATE connections SET server_ip=?, server_port=?, username=?, password=?, filter=? WHERE connection_name=?;");
        updatingQuery.addBindValue(server_ip);
        updatingQuery.addBindValue(server_port);
        updatingQuery.addBindValue(username);
        updatingQuery.addBindValue(password);
        updatingQuery.addBindValue(filter_string);
        updatingQuery.addBindValue(connection_name);
        updatingQuery.exec();
    }
    else
    {
        updatingQuery.prepare("INSERT INTO connections VALUES (?, ?, ?, ?, ?, ?);");
        updatingQuery.addBindValue(connection_name);
        updatingQuery.addBindValue(server_ip);
        updatingQuery.addBindValue(server_port);
        updatingQuery.addBindValue(username);
        updatingQuery.addBindValue(password);
        updatingQuery.addBindValue(filter_string);
       updatingQuery.exec();
    }

    ClearBoxes();

    /*** (2) ***/
    emit UpdateSideDock();
    PopulateConnectionsListWidget();

    // Disable the connection name lineedit
    ui->LE_ConnectionName->setDisabled(true);
    connectionBeingCreated = false;
}

void ConnectionManager::ItemSelected()
{
    // This slot needs to
    // (1) Fill in the form at the bottom when the item is double-clicked in the list widget.

    /*** (1) ***/
    ui->LE_FilterString->setEnabled(true);
    ui->LE_Password->setEnabled(true);
    ui->LE_Port->setEnabled(true);
    ui->LE_ServerIP->setEnabled(true);
    ui->LE_Username->setEnabled(true);

    connectionBeingCreated = false; // connection is NOT being created since an existing connection was clicked.
    ui->LE_ConnectionName->setDisabled(true); // disable the connection name field so it may not be modified.
    ui->PB_DeleteConnection->setEnabled(true); // since an active connection was selected, the delete option is enabled.
    ui->LA_ErrorStatus->setText("");
    ui->PB_Save->setEnabled(true);

    QSqlQuery selectedQuery(connectionsDatabase);

    selectedQuery.exec("SELECT * FROM connections");
    while (selectedQuery.next())
    {
        if (selectedQuery.value(0).toString() == ui->listWidget->currentItem()->text())
        {
            ui->LE_ConnectionName->setText(selectedQuery.value(0).toString());
            ui->LE_Username->setText(selectedQuery.value(3).toString());
            ui->LE_ServerIP->setText(selectedQuery.value(1).toString());
            ui->LE_Port->setText(selectedQuery.value(2).toString());
            ui->LE_Password->setText(selectedQuery.value(4).toString());
            ui->LE_FilterString->setText(selectedQuery.value(5).toString());
        }
    }
}

void ConnectionManager::DeleteConnection()
{
    QSqlQuery deleteQuery(connectionsDatabase);
    deleteQuery.prepare("DELETE FROM connections WHERE connection_name = ?");
    deleteQuery.addBindValue(ui->LE_ConnectionName->text());
    deleteQuery.exec();

    ClearBoxes();

    emit UpdateSideDock();
    PopulateConnectionsListWidget();
}

void ConnectionManager::ClearAllBoxes()
{
    ClearBoxes();
}

void ConnectionManager::CreateNewConnection()
{
    // This slot needs to create a new connection in the connection dialog.
    connectionBeingCreated = true; // a connection is being created (new was clicked)
    ui->LE_ConnectionName->setEnabled(true); // enable the connection name box
    ui->LE_FilterString->setEnabled(true);
    ui->LE_Password->setEnabled(true);
    ui->LE_Port->setEnabled(true);
    ui->LE_ServerIP->setEnabled(true);
    ui->LE_Username->setEnabled(true);
    ui->PB_DeleteConnection->setDisabled(true); // disable the delete connection box
    ClearAllBoxes();
}
